package cn.px.service.purchase.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.util.IdGeneratorUtils;
import cn.px.dao.bean.MyPage;
import cn.px.dao.dto.purchase.PurchaseContractMainListDTO;
import cn.px.dao.dto.purchase.PurchaseListDTO;
import cn.px.dao.entity.purchase.PurchaseContract;
import cn.px.dao.entity.purchase.PurchaseContractMainList;
import cn.px.dao.entity.purchase.PurchaseList;
import cn.px.dao.entity.purchase.PurchaseOrder;
import cn.px.dao.enums.FormActionEnum;
import cn.px.dao.enums.PurchaseListStatusEnum;
import cn.px.dao.enums.PurchaseTypeEnum;
import cn.px.dao.mapper.purchase.PurchaseContractMainListMapper;
import cn.px.dao.mapper.purchase.PurchaseListMapper;
import cn.px.dao.mapper.purchase.PurchaseOrderMapper;
import cn.px.dao.vo.query.purchase.PurchaseContractMainListVO;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.service.purchase.PurchaseContractMainListService;
import cn.px.service.purchase.PurchaseListService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 采购合同主清单 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2020,北京乾元坤和科技有限公司 All rights reserved.
 */
@AllArgsConstructor
@Service("purchaseContractMainListService")
public class PurchaseContractMainListServiceImpl extends BaseServiceImpl<PurchaseContractMainListMapper, PurchaseContractMainList, PurchaseContractMainListDTO> implements PurchaseContractMainListService {

    private final PurchaseListMapper purchaseListMapper;

    private final PurchaseListService listService;

    private final PurchaseOrderMapper orderMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDelete(List<String> ids) {
        Weekend<PurchaseList> updateWeekend = new Weekend<>(PurchaseList.class);
        WeekendCriteria<PurchaseList, Object> updateCriteria = updateWeekend.weekendCriteria();
        updateCriteria.andIn(PurchaseList::getContractMainListId, ids);
        PurchaseList list = new PurchaseList();
        list.setStatus(PurchaseListStatusEnum.PURCHASE_LIST_STATUS_ORDER.getValue());
        purchaseListMapper.updateByExampleSelective(list, updateWeekend);

        Weekend<PurchaseContractMainList> weekend = new Weekend<>(PurchaseContractMainList.class);
        WeekendCriteria<PurchaseContractMainList, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andIn(PurchaseContractMainList::getId, ids);
        mapper.deleteByExample(weekend);

        return 1;
    }

    @Override
    public AbstractPageResultBean<PurchaseContractMainListVO> selectPageList(PurchaseContractMainListDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    public AbstractPageResultBean<PurchaseContractMainList> selectPageInfo(PurchaseContractMainListDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PurchaseContractMainList saveModelByDTO(PurchaseContractMainListDTO model) {
        otherAttr(model, true);
        return super.saveModelByDTO(model);
    }

    @Override
    public void modModelByDTO(PurchaseContractMainListDTO model) {
        otherAttr(model, false);
        super.modModelByDTO(model);
    }

    /**
     * 添加其他属性
     *
     * @param model
     */
    private void otherAttr(PurchaseContractMainListDTO model, boolean addFlag) {
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleListByContract(PurchaseContract contract, List<Object> objects, Integer action) {
        if (CollectionUtils.isEmpty(objects)) {
            return;
        }
        Weekend<PurchaseList> weekend = new Weekend<>(PurchaseList.class);
        WeekendCriteria<PurchaseList, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andEqualTo(PurchaseList::getContractId, contract.getId());
        PurchaseList list = new PurchaseList();
        list.setStatus(PurchaseListStatusEnum.PURCHASE_LIST_STATUS_ORDER.getValue());
        purchaseListMapper.updateByExampleSelective(list, weekend);

        Weekend<PurchaseContractMainList> delete = new Weekend<>(PurchaseContractMainList.class);
        WeekendCriteria<PurchaseContractMainList, Object> criteria = delete.weekendCriteria();
        criteria.andEqualTo(PurchaseContractMainList::getContractId, contract.getId());
        mapper.deleteByExample(delete);
        if (FormActionEnum.DELETE.getValue().equals(action)) {
            List<String> ids = objects.stream().map(item -> {
                PurchaseContractMainListDTO listDTO = convert(item);
                return listDTO.getId();
            }).collect(Collectors.toList());
            batchDelete(ids);
        }
        if (FormActionEnum.ADD.getValue().equals(action)) {
            // 设备的更新状态再添加到主条款里面
            PurchaseOrder order = orderMapper.selectByPrimaryKey(contract.getPurchaseOrderId());
            if (order.getType().compareTo(PurchaseTypeEnum.PURCHASE_APPLY_TYPE_SB.getValue()) <= 0) {
                for (int i = objects.size() - 1; i >= 0; i--) {
                    PurchaseListDTO listDTO = convertForList(objects.get(i));
                    otherAttrForList(contract, listDTO, PurchaseListStatusEnum.PURCHASE_LIST_STATUS_CONTRACT.getValue());
                }
            }
            // 增加主条款以及随机清单
            for (int i = 0; i < objects.size(); i++) {
                PurchaseContractMainListDTO listDTO = convert(objects.get(i));
                otherAttr(contract, listDTO);
                listDTO.setId(IdGeneratorUtils.getObjectId());
                PurchaseContractMainList mainList = super.saveModelByDTO(listDTO);
                listService.handleListByContractMainList(mainList, listDTO.getAddList(), FormActionEnum.ADD.getValue());
            }
            return;
        }
        if (FormActionEnum.UPDATE.getValue().equals(action)) {
            for (int i = objects.size() - 1; i >= 0; i--) {
                PurchaseContractMainListDTO listDTO = convert(objects.get(i));
                otherAttr(contract, listDTO);
                super.modModelByDTO(listDTO);
                PurchaseContractMainList mainList = mapper.selectByPrimaryKey(listDTO.getId());
                listService.handleListByContractMainList(mainList, listDTO.getAddList(), FormActionEnum.ADD.getValue());
                listService.handleListByContractMainList(mainList, listDTO.getUpdateList(), FormActionEnum.UPDATE.getValue());
                listService.handleListByContractMainList(mainList, listDTO.getDeleteList(), FormActionEnum.DELETE.getValue());
            }
            return;
        }

    }

    /**
     * 类型转换
     *
     * @param obj
     * @return
     */
    private PurchaseContractMainListDTO convert(Object obj) {
        return JSON.parseObject(JSON.toJSONString(obj), PurchaseContractMainListDTO.class);
    }

    /**
     * 添加其他属性
     *
     * @param model
     */
    private void otherAttrForList(PurchaseContract contract, PurchaseListDTO model, Integer status) {
        PurchaseListDTO update = new PurchaseListDTO();
        update.setId(model.getId());
        update.setContractId(contract.getId());
        update.setStatus(status);
        listService.modModelByDTO(update);
    }

    /**
     * 类型转换
     *
     * @param obj
     * @return
     */
    private PurchaseListDTO convertForList(Object obj) {
        return JSON.parseObject(JSON.toJSONString(obj), PurchaseListDTO.class);
    }

    /**
     * 添加其他属性
     *
     * @param model
     */
    private void otherAttr(PurchaseContract contract, PurchaseContractMainListDTO model) {
        model.setDemandPlanId(contract.getDemandPlanId());
        model.setPurchasePlanId(contract.getPurchasePlanId());
        model.setPurchaseApplyId(contract.getPurchaseApplyId());
        model.setPurchaseOrderId(contract.getPurchaseOrderId());
        model.setContractId(contract.getId());
        model.setMoneyType(contract.getMoneyType());
        model.setExchangeRate(contract.getExchangeRate());
        model.setDollarExchangeRate(contract.getDollarExchangeRate());
//        model.setAccountExchangeRate(contract.getAccountExchangeRate());
    }
}
